package csm.common.security;

import java.security.SecureRandom;

public class GUIDTimer
{
	public GUIDTimer(SecureRandom rnd)
	{
		mLastTimeStamp = 0L;
		mClockCounter = 0;
		mRnd = rnd;

		initTimeStamps();
	}

	private void initTimeStamps()
	{
		mRnd.nextBytes(mClockSequence);
		byte tmp[] = new byte[1];
		mRnd.nextBytes(tmp);
		mClockCounter = tmp[0] & 0xff;
		mLastTimeStamp = 0L;
	}

	public void getTimestamp(byte uuidData[])
	{
		uuidData[8] = mClockSequence[0];
		uuidData[9] = mClockSequence[1];
		long now = System.currentTimeMillis();

		if (now < mLastTimeStamp)
			initTimeStamps();
		else if (now == mLastTimeStamp)
		{
			if ((long) mClockCounter == 10000L)
			{
				mClockCounter &= 0xff;
				do
				{
					try
					{
						Thread.sleep(1L);
					}
					catch (InterruptedException interruptedexception)
					{
					}

					now = System.currentTimeMillis();

				} while (now == mLastTimeStamp);

				mLastTimeStamp = now;
			}
		}
		else
		{
			mClockCounter &= 0xff;
			mLastTimeStamp = now;
		}

		now *= 10000L;
		now += 0x1b21dd213814000L;
		now += mClockCounter;

		int clockHi = (int) (now >>> 32);
		int clockLo = (int) now;

		uuidData[6] = (byte) (clockHi >>> 24);
		uuidData[7] = (byte) (clockHi >>> 16);
		uuidData[4] = (byte) (clockHi >>> 8);
		uuidData[5] = (byte) clockHi;
		uuidData[0] = (byte) (clockLo >>> 24);
		uuidData[1] = (byte) (clockLo >>> 16);
		uuidData[2] = (byte) (clockLo >>> 8);
		uuidData[3] = (byte) clockLo;

		mClockCounter++;
	}

	@SuppressWarnings("unused")
	private static final long kClockOffset = 0x1b21dd213814000L;
	@SuppressWarnings("unused")
	private static final long kClockMultiplier = 10000L;
	@SuppressWarnings("unused")
	private static final long kClockMultiplierL = 10000L;
	private final SecureRandom mRnd;
	private final byte mClockSequence[] = new byte[2];
	private long mLastTimeStamp;
	private int mClockCounter;
}
